-
-
Notifications
You must be signed in to change notification settings - Fork 14.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
stdenv: remove assumption of exactly two cross stages #251299
Conversation
no eval changes, gobject-introspection not broken. |
I don't think ofborg does a lot of cross eval, so 1% extra work seems rather significant. Maybe the new items in the stage list are significant (multiple 1% extra work is based on the total allocation stat, which is a decent proxy for the amount of work done. |
removed 2 of the no-op stages, left 1 in. |
3c3
< "cpuTime": 0.19761300086975098,
---
> "cpuTime": 0.19300399720668793,
5,7c5,7
< "bytes": 7536160,
< "elements": 374460,
< "number": 283780
---
> "bytes": 8005344,
> "elements": 394312,
> "number": 303178
11c11
< "totalBytes": 104882656
---
> "totalBytes": 116688640
14,24c14,24
< "bytes": 1682440,
< "concats": 7054,
< "elements": 210305
< },
< "nrAvoided": 393536,
< "nrFunctionCalls": 255442,
< "nrLookups": 113863,
< "nrOpUpdateValuesCopied": 3048123,
< "nrOpUpdates": 17927,
< "nrPrimOpCalls": 175909,
< "nrThunks": 681368,
---
> "bytes": 1986528,
> "concats": 7060,
> "elements": 248316
> },
> "nrAvoided": 412934,
> "nrFunctionCalls": 274757,
> "nrLookups": 114224,
> "nrOpUpdateValuesCopied": 3363935,
> "nrOpUpdates": 18007,
> "nrPrimOpCalls": 176018,
> "nrThunks": 719493,
26,28c26,28
< "bytes": 63105280,
< "elements": 3841922,
< "number": 102158
---
> "bytes": 71197280,
> "elements": 4328578,
> "number": 121252
38c38
< "number": 22681
---
> "number": 22683
41,42c41,42
< "bytes": 19680096,
< "number": 820004
---
> "bytes": 21508920,
> "number": 896205 |
Previously, stdenv used `adjacentPackages==null` to signal that `actuallySplice` should be `false`. Let's pass it explicitly for greater clarity.
It's quite difficult to understand what this `selfBuild` parameter is signaling, but it turns out to simply indicate which stages have any kind of cross compilation (i.e. either build!=host or host!=target). Let's check that condition directly for greater clarity.
The native stdenv bootstrap (e.g. `pkgs/stdenv/linux/default.nix`) is very elegantly structured as a sequence of arbitrarily-many stages. This makes it easy to refactor and modularize and reuse, because if a stage gets too complicated we can just split it up into two separate sequential stages. We can also insert optional stages. Unfortunately we can't do the same thing with cross-compiled stdenvs, because `adjacentPackages` includes the hardwired assumption that there are exactly two stages after the end of the native bootstrap stage sequence: - The (build==host)!=target stage - The build!=(host==target) stage This commit eliminates that assumption. Instead of resolving things like `pkgsBuildHost` to `prevStage`, we instead *search backwards* for the most recent stage which creates packages on our buildPlatform and for our hostPlatform. This commit should not affect eval. Note that `pkgsTargetTarget`, which becomes `targetPackages` still has hardwired assumptions. I think setting `pkgsTargetTarget` to `nextStage` is just flat-out wrong for every stage except the "main" stage (the `build!=(host==target)` stage), but I fear that there may be code that relies on the particular way that it is wrong. It looks like `pkgsTargetTarget` and `targetPackages` exist exclusively in order to provide access to the `postStage` hack; I intend to submit a separate PR that `throw`s if it is used in any other way, to see what breaks. Co-authored-by: Robert Hensing <roberth@users.noreply.github.com>
This commit inserts extra stages into the cross-compilation stdenv bootstrap in order to prevent assumptions about the number of stages from creeping back in (see previous commit). If this commit is used without the previous commit, eval will fail badly. The no-op stages added by this commit serve as an example of what wasn't possible before the PR which includes them. Co-authored-by: Robert Hensing <roberth@users.noreply.github.com>
Squashed, rebased. There is now only one no-op stage, but with an expanded comment explaining why it thwarts unjustified assumptions, and a mention of the other two (removed) no-op stages in case re-introducing them helps with troubleshooting. |
Doesn't this break "identity cross compilation"? I.e. forcing a round of cross bootstrapping even though This is funny to me because I sort of wanted to go in the opposite direction: the native bootstraps do not need all these stages, instead there should be just one "with bootstrapping tools" stage and then one "without bootstrapping tools" stage. But I am willing to do this because I don't yet have time to do rework things as I have wanted to for years, and @amjoseph-nixpkgs is motivated and does have time for putting in the work. |
This is not describing this PR, but this actually sounds quite bad to me. The |
I've revised this to:
(Text moved to #263684 since it will remain useful even after this PR is closed).
It's actually the other way around: our native bootstrap has more steps than our cross bootstrap.
Don't worry; I have absolutely no intention of reducing our cross bootstrap's capability. If I can't make it work for every case in It's quite likely that the end result will have certain stages skipped as totally unnecessary if |
I don't quite understand what you mean here. Could you give an example (like
@Ericson2314 I would like to hear more about this! If I haven't already. |
If you want to see an example of the problem this PR solves, cherry pick just the "stdenv: cross: insert no-op stages" commit and
nix-instantiate . -A pkgsCross.<anything>
.Motivation
This removes one of the last obstacles to unifying our native and cross bootstraps, which will allow to eliminate all the
libcCrossChooser
and simply reuse the relevant stages frompkgs/stdenv/linux/default.nix
instead.Description of changes
The native stdenv bootstrap (e.g.
pkgs/stdenv/linux/default.nix
) is very elegantly structured as a sequence of arbitrarily-many stages. This makes it easy to refactor and modularize and reuse, because if a stage gets too complicated we can just split it up into two separate sequential stages. We can also insert optional stages.Unfortunately we can't do the same thing with cross-compiled stdenvs, because
adjacentPackages
includes the hardwired assumption that there are exactly two stages after the end of the native bootstrap stage sequence:(build==host)!=target
stagebuild!=(host==target)
stageThis PR eliminates that assumption.
Instead of resolving things like
pkgsBuildHost
toprevStage
, we instead search backwards for the most recent stage which creates packages on our buildPlatform and for our hostPlatform.This PR should not affect eval.
Note that
pkgsTargetTarget
, which becomestargetPackages
still has hardwired assumptions. I think settingpkgsTargetTarget
tonextStage
is just flat-out wrong for every stage except the "main" stage (thebuild!=(host==target)
stage), but I fear that there may be code that relies on the particular way that it is wrong. It looks likepkgsTargetTarget
andtargetPackages
exist exclusively in order to provide access to thepostStage
hack; I intend to submit a separate PR thatthrow
s if it is used in any other way, to see what breaks.Things done
sandbox = true
set innix.conf
? (See Nix manual)nix-shell -p nixpkgs-review --run "nixpkgs-review rev HEAD"
. Note: all changes have to be committed, also see nixpkgs-review usage./result/bin/
)